package com.sunrise.financeiro.repositorio;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.sunrise.financeiro.repositorio.iface.GrupoCategoriaFinanceiraDao;
import com.sunrise.generico.acesso.DaoService;
import com.sunrise.generico.entidade.GrupoCategoriaFinanceira;
import com.sunrise.generico.enums.TipoMovimentacaoFinanceira;
import com.sunrise.generico.visao.Filtro;

@Repository
public class GrupoCategoriaFinanceiraDaoImpl extends DaoService<GrupoCategoriaFinanceira> implements
		GrupoCategoriaFinanceiraDao {

	public List<GrupoCategoriaFinanceira> listarOrdenado() {
		List<GrupoCategoriaFinanceira> list = listarAtivos();
		Collections.sort(list, new Comparator<GrupoCategoriaFinanceira>() {

			@Override
			public int compare(GrupoCategoriaFinanceira o1, GrupoCategoriaFinanceira o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public List<GrupoCategoriaFinanceira> search(GrupoCategoriaFinanceira ex) {
		List<GrupoCategoriaFinanceira> list = searchByExample(GrupoCategoriaFinanceira.class, ex);
		Collections.sort(list, new Comparator<GrupoCategoriaFinanceira>() {

			@Override
			public int compare(GrupoCategoriaFinanceira o1, GrupoCategoriaFinanceira o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public GrupoCategoriaFinanceira getById(Long id) {
		return getById(id, GrupoCategoriaFinanceira.class);
	}
	

	@SuppressWarnings("unchecked")
	public List<GrupoCategoriaFinanceira> listarAtivos() {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);
		crit.add(Restrictions.eq("ativo", Boolean.TRUE));
		return crit.list();
	}

	
	@SuppressWarnings("unchecked")
	@Override
	public List<GrupoCategoriaFinanceira> listarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);
		crit.add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE));
		crit.add(Restrictions.eq("ativo", Boolean.TRUE));
		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<GrupoCategoriaFinanceira> buscarPorFiltros(Filtro filtro) {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);
		if (filtro.getNome() != null) {
			crit.add(Restrictions.ilike("nome", filtro.getNome(), MatchMode.ANYWHERE));
		}

		if (filtro.getTipoMovimentacaoFinanceira() != null) {
			crit.add(Restrictions.eq("tipoMovimentacaoFinanceira", filtro.getTipoMovimentacaoFinanceira()));
		}

		if (filtro.getAtivo() != null) {
			crit.add(Restrictions.eq("ativo", filtro.getAtivo().getCodigo()));
		}

		crit.addOrder(Order.asc("nome"));
		return crit.list();
	}

	@Override
	public GrupoCategoriaFinanceira buscarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);
		crit.add(Restrictions.eq("nome", nome).ignoreCase());
		crit.add(Restrictions.eq("ativo", Boolean.TRUE));
		return (GrupoCategoriaFinanceira) crit.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<GrupoCategoriaFinanceira> buscarGrupoCategoriaFinanceiraPorNome(String[] nomes) {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);
		Disjunction or = Restrictions.disjunction();
		crit.add(or);
		for (String nome : nomes) {
			or.add(Restrictions.eq("nome", nome).ignoreCase());
		}
		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<GrupoCategoriaFinanceira> buscarPorTipoMovimentacao(
			TipoMovimentacaoFinanceira tipoMovimentacaoFinanceira) {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);

		if (tipoMovimentacaoFinanceira != null) {
			crit.add(Restrictions.eq("tipoMovimentacaoFinanceira", tipoMovimentacaoFinanceira));
		}

		crit.add(Restrictions.eq("ativo", Boolean.TRUE));

		return crit.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<GrupoCategoriaFinanceira> listarGruposPorTipoMovimentacao(TipoMovimentacaoFinanceira despesa) {
		Criteria crit = getSession().createCriteria(GrupoCategoriaFinanceira.class);
		crit.add(Restrictions.eq("tipoMovimentacaoFinanceira", despesa));
		return crit.list();
	}

}
